package com.iflytek.uoamp.agent.monitor.job;

import com.alibaba.fastjson.JSON;
import com.iflytek.uoamp.agent.core.sender.monitorsender.requestObj.MonitorItemConfig;
import com.iflytek.uoamp.agent.core.sender.monitorsender.requestObj.MonitorItemResult;
import com.iflytek.uoamp.agent.monitor.find.CMDExextor;
import com.iflytek.uoamp.agent.monitor.find.CMDExextor.ShellResult;

import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;

import java.io.File;
import java.io.IOException;

public class ShellExecutor {
	
	private MonitorItemConfig itemConfig;
	
	public ShellExecutor(MonitorItemConfig itemConfig){
		this.itemConfig = itemConfig;
	}

	public String getCommand(){
		return itemConfig.getServerUrl();
	}
	
	public String getRestartCommand(){
		return itemConfig.getXml();
	}
	
	/**
	 * 执行检查命令
	 * @return
	 */
	public MonitorItemResult check(){
		File file = new File("");
		String dir = file.getAbsolutePath();
		String serverUrl = getCommand();
		String command = dir+"/cmd/"+serverUrl;
		
		//bxwan add
		String commName = serverUrl.substring(0, serverUrl.indexOf(" "));//插件带后缀的名字
		String commPar = serverUrl.substring(serverUrl.indexOf(" "),serverUrl.length());//参数
		String comd = dir+"/cmd/"+ commName;
		Logger.getRootLogger().info("run command "+(command)+" start");
		ShellResult result = null;
		//判断是否是.zip文件
		if(comd.endsWith(".zip")){
			String zipCommand = comd.split(".zip")[0];
			String excuteFileAbsolutePath = getFileList(zipCommand,"main");
			if(StringUtils.isNotBlank(excuteFileAbsolutePath)){
				command = excuteFileAbsolutePath+commPar;
			}
		}
		
		result = CMDExextor.execut(command, false);
		Logger.getRootLogger().info("run command "+(command)+" finish!Result=========>"+ JSON.toJSONString(result));

		//如果返回code不为0，则进行重新执行
        ShellResult tryagentReslut = null;
		if(0 != result.code){
            tryagentReslut = tryAgain(command);
		}
        if(tryagentReslut != null){
            result = tryagentReslut;
        }
		MonitorItemResult monitorResult = new MonitorItemResult();
		monitorResult.setComponentType("checklocal");
		monitorResult.setHost(itemConfig.getHost());
		monitorResult.setServerDesc(itemConfig.getServerDesc());
		monitorResult.setReturnCode(result.code+"");
		monitorResult.setServicesObjectId(itemConfig.getServicesObjectId());
		monitorResult.setHostObjectId(itemConfig.getHostObjectId());
		String resultOutput = result.output == null ? "":result.output;
		String errOutput = result.errOutput;
		if (!StringUtils.isBlank(errOutput)) {
			resultOutput = resultOutput.concat(" & errorInfor:").concat(errOutput);
		}
		monitorResult.setOutput(resultOutput);
		monitorResult.setUptime(itemConfig.getUptime());
		Logger.getRootLogger().info("check result is Service " + itemConfig.getServerDesc() + " return_code:" + monitorResult.getReturnCode() + " output: " + monitorResult.getOutput());
		return monitorResult;
	}
	
	public void restart(){
		String command = getRestartCommand();
		try {
			Process ps = Runtime.getRuntime().exec(command);
			ps.waitFor();
			Logger.getRootLogger().info("run restart command "+command+" finish");
			
		} catch (IOException e) {
			Logger.getRootLogger().error(e.getMessage(),e);
		} catch (InterruptedException e) {
			Logger.getRootLogger().error(e.getMessage(),e);
		}  
	}
	
	//脚本返回错误代码重试功能
	private ShellResult tryAgain(String command){ 
		ShellResult result = null;
		int maxCheck = this.itemConfig.getMaxCheckAttempts(); 
		for (int i = 0; i < maxCheck; i++) {
			result = CMDExextor.execut(command, false);
			Logger.getRootLogger().info(command+"第"+(i+1)+"次重试！结果为："+JSON.toJSONString(result)+"================maxCheck="+maxCheck);
			if (0 != result.code) {
				try {
					//等待500ms之后再次重试
					Thread.sleep(500);
				} catch (InterruptedException e) {
					Logger.getRootLogger().error("tryAgain fail!", e);
				}
			}else{
				return result;
			}
		}
		return result;
	}
	
	
	public static String getFileList(String strPath,String fileName) {
        File dir = new File(strPath);
        File[] files = dir.listFiles(); // 该文件目录下文件全部放入数组
        if (files != null) {
            for (int i = 0; i < files.length; i++) {
                String filename = files[i].getName();
                if (files[i].isDirectory()) { // 判断是文件还是文件夹
                    getFileList(files[i].getAbsolutePath(),fileName); // 获取文件绝对路径
                } else if (filename.startsWith(fileName)) { // 判断文件名是否以filename开始
                    String strFileName = files[i].getAbsolutePath();
                    return strFileName;
                } else {
                    continue;
                }
            }
        }
        return "";
    }
}
